package com.zoe.vhr.filter;

import com.zoe.vhr.enums.RedisKeyEnum;
import com.zoe.vhr.model.Menu;
import com.zoe.vhr.model.Role;
import com.zoe.vhr.service.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.util.AntPathMatcher;

import java.util.Collection;
import java.util.List;

/**
 * @Author Zoe.Zhang
 * @Date: 2021/07/31
 * @Description 主要根据用户的请求url, 分析这个url对应所需要的角色
 */
@Configuration
public class MyFilterInvocationSecurityMetaDataSource implements FilterInvocationSecurityMetadataSource {
    private static final Logger logger = LoggerFactory.getLogger(MyFilterInvocationSecurityMetaDataSource.class);

    @Autowired
    RedisService redisService;

    List<Menu> menus;

    AntPathMatcher antPathMatcher = new AntPathMatcher();


    /**
     * 处理请求的对象
     *
     * @param o 用户请求的对象
     * @return ConfigAttribute 当前路径所需要的角色列表
     * @throws IllegalArgumentException
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        // 获取用户请求的地址
        FilterInvocation filterInvocation = (FilterInvocation) o;
        String requestUrl = filterInvocation.getRequestUrl();

        List<Menu> menus = redisService.getCacheObject(RedisKeyEnum.ALL_MENUS.getKey());

        this.menus = menus;

        for (Menu menu : this.menus) {
            if (antPathMatcher.match(menu.getUrl(), requestUrl)) {
                List<Role> roles = menu.getRoles();
                // 如果请求的url和menu的url匹配上了，把当前路径所需要的 权限name  添加到数组中;
                String[] roleArr = roles.stream().map(x -> x.getName()).toArray(String[]::new);
                return SecurityConfig.createList(roleArr);
            }
        }

        // 如果没有匹配上，则默认给一个标识符，MyAccessDecisionManager 决策管理器会用到
        return SecurityConfig.createList("ROLE_LOGIN");
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        logger.info("supportssupportssupportssupportssupportssupportssupportssupportssupportssupportssupportssupportssupports");
        return true;
    }

}
